package com.hujifang.elasticsearch.utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Title: Properties工具类<br/>
 */
public class PropUtil {
	
	private static ConcurrentHashMap<String,Properties> propsMap = new ConcurrentHashMap<>();
    
	/**
	 * 通过文件路径获得properties对象
	 * @param filePath
	 * @return
	 */
	public static Properties getPropByFile(String filePath){
		Properties prop = null;
        InputStream in =null;
        try {
        	synchronized (propsMap) {
				prop = propsMap.get(filePath);
				if (prop == null) {
					prop = new Properties();
					if(filePath.startsWith("jar:")){
						in = PropUtil.class.getClassLoader().getResourceAsStream(filePath.substring(filePath.indexOf("jar!/")+5));
						if(in==null)  in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath.substring(filePath.indexOf("jar!/")+5));
					}else{
						in = new BufferedInputStream(new FileInputStream(new File(new URI(filePath))));
					}
					prop.load(in);
					if (prop != null) {
						propsMap.put(filePath, prop);
					}
				}
			}
        }catch (IOException e) {
            throw new RuntimeException("File Not Found: "+filePath);
        }catch(URISyntaxException e){
        	throw new RuntimeException("File Not Found: "+e.getMessage());
		}finally{
        	try {
        		if(in!=null)
        			in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
		return prop;
	}
	
	/**
	 * 通过相对资源路径路径获得properties对象
	 * @param filePath
	 * @return
	 */
	public static Properties getProp(String fileUrl){
		URL url = PropUtil.class.getClassLoader().getResource(fileUrl); 
		if(url==null)
			url = Thread.currentThread().getContextClassLoader().getResource(fileUrl);
		return getPropByFile(url.toString());
	}
	private static String getValue(Properties prop,String key){
		if(prop==null){
			return null;
		}
		return  prop.getProperty(key);
	}
	
	private static String getValue(Properties prop,String key,String defaultValue){
		if(prop==null){
			return null;
		}
		return  prop.getProperty(key,defaultValue);
	}
	
	/**
	 * 通过相对资源路径路径获得properties文件的key的值
	 * @param fileUrl 
	 * @param key
	 * @return
	 */
	public static String get(String fileUrl,String key){
		Properties prop=getProp(fileUrl);
		return getValue(prop,key);
	}
	/**
	 * 通过相对资源路径路径获得properties文件的key的值
	 * @param fileUrl
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	public static String get(String fileUrl,String key,String defaultValue){
		Properties prop=getProp(fileUrl);
		return getValue(prop,key,defaultValue);
	}
	
	/**
	 * 通过文件路径获得properties文件的key的值
	 * @param propFile
	 * @param key
	 * @return
	 */
	public static String getByFile(String propFile,String key){
		Properties prop=getPropByFile(propFile);
		return getValue(prop,key);
	}
	//重載的方法
	public static String getByFile(String propFile,String key,String defaultValue){
		Properties prop=getPropByFile(propFile);
		return getValue(prop,key,defaultValue);
	}
	
	/**
	 * 更新properties文件
	 * @param key
	 * @param value
	 * @param filePath
	 */
    public static void updateData(String key, String value,String filePath) {
        Properties prop = new Properties();
        InputStream fis = null;
        OutputStream fos = null;
        try {
			URL url = PropUtil.class.getClassLoader().getResource(filePath);
			File file = new File(url.toURI());
			File parentF = file.getParentFile();
			if (!parentF.exists()) {
				parentF.mkdirs();
			}
			if (!file.exists()) {
				file.createNewFile();
			}
			fis = new FileInputStream(file);
			prop.load(fis);
			fis.close();//一定要在修改值之前关闭fis
			fos = new FileOutputStream(file);
			prop.setProperty(key, value);
			prop.store(fos, "Update '" + key + "' value");
			fos.close();
			propsMap.remove(key);
        } catch (IOException e) {
        	throw new RuntimeException("Visit " + filePath + " for updating "
                  + value + " value error");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally{
            try {
            	if(fos!=null)
            		fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
            	if(fos!=null)
            		fos.close();
            } catch (IOException e) {
            	e.printStackTrace();
            }
        }
    }
    
    /**
     * 清空此工具对象的缓存
     */
    public static void cleanPropMap(){
		propsMap.clear();
		propsMap = new ConcurrentHashMap<String, Properties>();
    }
    
}